Stencil is an incredible tool that helps you create web components that you can use with Vanilla Javascript and some frameworks like React, Vue, Angular …, and combine with storybook. You can offer an incredible tool for all of our community. In this article, I will show you how to save time and create all your stories in an automatic way.
Note: For this project, we are assuming that you have some basic knowledge of StencilJS
Creating our project
First, we need a stencil project for web components. You can do this by following the instructions on the Stencil page. Also, we need to install stencil/sass
and clsx
. Your project should look something like this in your browser:
Stencil starter project
Now, we will create our own component and will call mine my-button. It will have five different props (color, disabled, elevation, shape and size). Feel free to use your own component. It should look something like this:
With the following style:
Once you have it, use it on your index.html
, and see the results. If you would have used my example you should see something like this:
Great!! Now, we have a component to start working on.
…
Installing and configuring storybook
Let’s start with the storybook configuration, since the stencil option for web components is still in alpha, we will install the storybook for HTML.
Use the following command on your project to install storybook:
npx sb init
Note: For this project, we are using @storybook/html version ^6.1.2, down versions will not work.
Once storybook is up and running, add the next dependencies:
npm install npm-run-all @storybook/addon-essentials @storybook/addon-notes @storybook/addon-viewport case --save-dev
We will use the addon-essentials to install controls, so that anyone can interact dynamically with our components; addon-notes to charge the documentation generated automatically by stencil; addon-viewport (optional) to check our components on different screen sizes; case and npm-run-all will be used for our script to generate each story, we will cover them later. Now, let’s go to the .storybook
directory and modify the main.js
file as follows:
.storybook/main.js
We have changed the default storybook webpack configuration to charge our automated stories in a correct way. Now, we need to build the last version of our components in order for them to work in our stories. For this purpose, we need to add the next scripts to our package.json
:
"storybook.run": "start-storybook -p 6006 -s dist",
"storybook": "npm-run-all --parallel build storybook.run",
"build-storybook": "build-storybook -c ./.storybook -o ../public"
If you run storybook now, you should have a readme file created by stencil inside each component, we will use them in our automated stories. To do this first we have to create a global.d.ts file inside your src directory with the next line inside:
global.d.ts
Our first story
Our next step is to create our first story. Inside our my-button component directory, create a file called my-button.stories.tsx
, add the next code:
my-button.stories.tsx
Here, we are importing our readme file to show it as the documentation, later we will see how storybook will manage it.
Creating our script to automate stories
Now, let’s start working on the creation of our automated stories. For this purpose, we will create a script dedicated to this. Inside your .storybook directory, create a stories directory with a file called automatedStories.js. From now on we will be adding a lot of code inside this file, so let’s start. Our first step is to create the function that will be in charge of receiving each component and story created to complete with our base render. It should look like this:
.storybook/stories/automatedStories.js (part 1)
This function receives our configs and checks if we have an object (which is the way we will create the stories we want to be processed by our script) or a function. In case, it is a function, we will let storybook manage it, but the other way we want to use our own script. Now, let’s add our configs generator:
.storybook/stories/automatedStories.js (part 2)
Here, we are getting all our Stencil Components and object for each of them who will have our custom configuration. This configuration includes our Component; states, which will be use to write extra renders we want to add to our story; args, which will include our props; argTypes, which will specify the control (check addon-controls) we want to use for each arg; and notes which will load our readme files. We have to clean our notes because addon-notes has some issues rendering tables.
Now that we have our configs covered, we can write our function to create stories, add the next code:
.storybook/stories/automatedStories.js (part 3)
Here, we are adding each stories, creating first our automated story. We are getting our props from our controls (I will explain how to do this later in our getPropsWithControlValues), adding them for our first story. We are adding a children with the createNodes function so our component is not empty inside, notice that this is optional, and creating our component element to send them to our special template, to create our template add the next function:
.storybook/stories/automatedStories.js (part 4)
Notice that you have to add our args, argTypes and notes to our story options, so they connect to our story.
Now, let’s see how to get our controls generated checking each of the stencil properties’ types, the format for generate the controls, it can be checked here:
.storybook/stories/automatedStories.js (part 5)
Rendering our stories
Now, with all of this set we have our automated stories script finished, our last step is to use this script. Storybook has the file called preview.js
to control the way stories are rendered, find/create it inside our .storybook
directory, we will modify it as follows, to load the stories the way we want to.
.storybook/preview.js
Lets analyze what are we doing? We are creating our collection (My Components) and getting all our previously build components and all our created stories. Once this is done, we are creating a function that will call each collection and use our script (buildStencilStories) to generate each story automatically.
Now, add the stories.js file to each component, following the example metioned before. Run storybook and see all your stories with its own controls generated automatically. The final result should look as follows:
Autogenerated story
If you are having problems reproducing this, you can check the original code on the repo (https://github.com/MagalyMJ/stencil-automated-stories).
Written by